home *** CD-ROM | disk | FTP | other *** search
/ Disc to the Future 2 / Disc to the Future Part II Programmer's Reference (Wayzata Technology)(6013)(1992).bin / MAC / THINKC / TCL1 / CSPINNER / CSPINNER.C < prev    next >
Text File  |  1990-12-20  |  4KB  |  144 lines

  1. /*
  2.     CSpinner.c
  3.     
  4.     Implements a spinning cursor. A list of cursors is specified with an
  5.     'acur' resource. Repeatedly invoking the Spin() method sequences
  6.     through the list of cursors.
  7.     
  8.     SUPERCLASS = CObject.c
  9.     
  10.     Copyright ⌐ 1990 Ursa Major Software. All rights reserved.
  11. */
  12.  
  13. #include "CSpinner.h"
  14.  
  15. typedef    struct    acurCURS    {            /* For each cursor in an 'acur'        */
  16.     short    resID;                        /*   CURS resource ID                */
  17.     short    padding;                    /*   Two bytes of padding            */
  18. } acurCURS;
  19.  
  20. typedef    struct    acurTemplate    {        /* Resource template for 'acur'        */
  21.     short        numCursors;                /*   Number of cursors in list        */
  22.     short        counter;                /*   Counter (not used by us)        */
  23.     acurCURS    CURSlist[];                /*   'CURS' ID/padding pairs        */
  24. } acurTemplate, **acurTemplateH;
  25.  
  26.  
  27. /*
  28.  *    Initialize a Spinner object
  29.  */
  30.  
  31. void    CSpinner::ISpinner(
  32.     short    acurID,                        /* 'acur' resource ID                */
  33.     short    aThreshold,                    /* Tick delay before first spin        */
  34.     short    anInterval)                    /* Ticks between spins                */
  35. {
  36.     register acurTemplateH    tempH;        /* 'acur' handle with entries        */
  37.                                         /*   as ID & padding pairs            */
  38.     register short            i;            /* Loop counter                        */
  39.     register CursHandle        aCursor;    /* Handle to 'CURS' resource        */
  40.     
  41.                                         /* Cursor IDs are in an 'acur'        */
  42.                                         /*   resource                        */
  43.     tempH = (acurTemplateH) GetResource('acur', acurID);
  44.     
  45.     DetachResource(tempH);                /* We are going to change the        */
  46.     HNoPurge(tempH);                    /*   'acur' resource in memory.        */
  47.                                         /*   Treat it as a regular handle    */
  48.                                         /*   and make it nonpurgeable.        */
  49.     
  50.         /* Cursor IDs list entries in the 'acur' are 4 bytes long.    */
  51.         /* The first 2 bytes are a 'CURS' resource ID and the        */
  52.         /* last 2 bytes are padding. This is so that the ID/padding    */
  53.         /* entry can be replaced with a handle (4 bytes long) to    */
  54.         /* the corresponding 'CURS' resource at runtime. "tempH"    */
  55.         /* and "acurH" both refer to the same handle. "tempH"        */
  56.         /* treats the entries as ID/padding pairs, whereas "acurH"    */
  57.         /* treats the entries as cursor handles.                    */
  58.         
  59.     acurH = (acurHand) tempH;
  60.     
  61.     for (i = 0; i < (**tempH).numCursors; i++) {
  62.                                         /* Get handle to Cursor                */
  63.         aCursor = GetCursor((**tempH).CURSlist[i].resID);
  64.         HNoPurge(aCursor);                /* Make it nonpurgeable                */
  65.         
  66.                                         /* Replace 'CURS' ID/padding pairs    */
  67.                                         /*   with a handle to the Cursor    */
  68.         (**acurH).cursors[i] = aCursor;
  69.     }
  70.     
  71.     SetTimes(aThreshold, anInterval);    /* Specify delay times                */
  72.     Reset();                            /* Initialize counters                */
  73. }
  74.  
  75.  
  76. /*
  77.  *    Dispose of a Spinner
  78.  */
  79.  
  80. void    CSpinner::Dispose()
  81. {
  82.     DisposHandle(acurH);                /* Throw out our modified copy        */
  83.                                         /*   of the 'acur' resource            */
  84. }
  85.  
  86.  
  87. /*
  88.  *    Reset counters to initial values. Subsequent spins will start with
  89.  *    the first cursor and will occur after the "threshold" delay.
  90.  */
  91.  
  92. void    CSpinner::Reset()
  93. {
  94.     cursIndex = 0;                        /* Start with the first cursor        */
  95.     nextSpinTime = 0;                    /* Indicates first spin is next        */
  96. }
  97.  
  98.  
  99. /*
  100.  *    Specifiy values for the threshold delay before the first spin
  101.  *    and the interval between spins
  102.  */
  103.  
  104. void    CSpinner::SetTimes(
  105.     short    newThreshold,
  106.     short    newInterval)
  107. {
  108.     threshold = newThreshold;            /* Set instance variables            */
  109.     interval = newInterval;
  110. }
  111.  
  112.  
  113. /*
  114.  *    Spin the cursor. Send this message repeatedly during long delays
  115.  *    to spin the cursor. Cursor spinning is accomplished by changing
  116.  *    the cursor after a specified time interval.
  117.  */
  118.  
  119. void    CSpinner::Spin()
  120. {
  121.     register long    theTickCount;
  122.     
  123.     theTickCount = TickCount();            /* Time in ticks since startup        */
  124.     
  125.     if (nextSpinTime == 0) {            /* Cursor has not yet spun            */
  126.                                         /* Set time counter so that the        */
  127.                                         /*   first spin will occur after    */
  128.                                         /*   "threshold" ticks                */
  129.         nextSpinTime = theTickCount + threshold;
  130.     
  131.     } else if (theTickCount >= nextSpinTime) {
  132.                                         /* Enough time has passed. Change    */
  133.                                         /*   the cursor                        */
  134.         SetCursor(*(**acurH).cursors[cursIndex]);
  135.         
  136.         cursIndex++;                    /* Increment cursor index            */
  137.         if (cursIndex >= (**acurH).numCursors) {
  138.             cursIndex = 0;                /* Wrap around to the first one        */
  139.         }
  140.                                         /* Next spin will occur after at    */
  141.                                         /*   least "interval" ticks            */
  142.         nextSpinTime = theTickCount + interval;
  143.     }
  144. }